/*
 * @lc app=leetcode.cn id=994 lang=cpp
 *
 * [994] 腐烂的橘子
 *
 * https://leetcode.cn/problems/rotting-oranges/description/
 *
 * algorithms
 * Medium (51.35%)
 * Likes:    845
 * Dislikes: 0
 * Total Accepted:    167.8K
 * Total Submissions: 326.5K
 * Testcase Example:  '[[2,1,1],[1,1,0],[0,1,1]]'
 *
 * 在给定的 m x n 网格 grid 中，每个单元格可以有以下三个值之一：
 *
 *
 * 值 0 代表空单元格；
 * 值 1 代表新鲜橘子；
 * 值 2 代表腐烂的橘子。
 *
 *
 * 每分钟，腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。
 *
 * 返回
 * 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能，返回 -1 。
 *
 *
 *
 * 示例 1：
 *
 *
 *
 *
 * 输入：grid = [[2,1,1],[1,1,0],[0,1,1]]
 * 输出：4
 *
 *
 * 示例 2：
 *
 *
 * 输入：grid = [[2,1,1],[0,1,1],[1,0,1]]
 * 输出：-1
 * 解释：左下角的橘子（第 2 行， 第 0 列）永远不会腐烂，因为腐烂只会发生在 4
 * 个方向上。
 *
 *
 * 示例 3：
 *
 *
 * 输入：grid = [[0,2]]
 * 输出：0
 * 解释：因为 0 分钟时已经没有新鲜橘子了，所以答案就是 0 。
 *
 *
 *
 *
 * 提示：
 *
 *
 * m == grid.length
 * n == grid[i].length
 * 1 <= m, n <= 10
 * grid[i][j] 仅为 0、1 或 2
 *
 *
 */
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

// @lc code=start

class Solution {
 public:
  int orangesRotting(vector<vector<int>> &grid) {
    queue<pair<int, int>> q;
    int num = 0, ans = 0, n = grid.size(), m = grid[0].size();
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        if (grid[i][j] == 2) q.push({i, j});
        if (grid[i][j] == 1) num++;
      }
    }
    while (q.size() && num) {
      int sz = q.size();
      for (int i = 0; i < sz; i++) {
        int x = q.front().first, y = q.front().second;
        q.pop();
        if (x - 1 >= 0 && grid[x - 1][y] == 1) {
          num--;
          grid[x - 1][y] = 2;
          q.push({x - 1, y});
        }
        if (x + 1 < n && grid[x + 1][y] == 1) {
          num--;
          grid[x + 1][y] = 2;
          q.push({x + 1, y});
        }
        if (y - 1 >= 0 && grid[x][y - 1] == 1) {
          num--;
          grid[x][y - 1] = 2;
          q.push({x, y - 1});
        }
        if (y + 1 < m && grid[x][y + 1] == 1) {
          num--;
          grid[x][y + 1] = 2;
          q.push({x, y + 1});
        }
      }
      ans++;
    }
    return num > 0 ? -1 : ans;
  }
};
// @lc code=end
